/*
 * @Author: ZAL 2177624751@qq.com
 * @Date: 2025-03-29 15:04:15
 * @LastEditors: ZAL 2177624751@qq.com
 * @LastEditTime: 2025-03-31 16:39:56
 * @FilePath: \shop_app_vue3d:\Users\21776\Desktop\毕设\fruit_backded\src\main\java\com\fruitshop\controller\UserController.java
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
package com.fruitshop.controller;

import com.fruitshop.dto.UserLoginDTO;
import com.fruitshop.service.UserService;
import com.fruitshop.util.JwtUtil;
import com.fruitshop.util.WxUtil;
import com.fruitshop.vo.ResultVO;
import com.fruitshop.vo.UserInfoVO;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.Map;
import java.util.UUID;

/**
 * 用户控制器
 */
@Slf4j
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {
    
    private final UserService userService;
    private final WxUtil wxUtil;
    private final JwtUtil jwtUtil;
    
    /**
     * 用户登录
     *
     * @param loginDTO 登录数据
     * @return 用户信息
     */
    @PostMapping("/login")
    public ResultVO<UserInfoVO> login(@RequestBody @Valid UserLoginDTO loginDTO) {
        log.info("接收到登录请求: {}", loginDTO);
        try {
            UserInfoVO userInfoVO = userService.login(loginDTO);
            log.info("登录成功: {}", userInfoVO);
            return ResultVO.success(userInfoVO);
        } catch (Exception e) {
            log.error("登录失败", e);
            return ResultVO.error(e.getMessage());
        }
    }
    
    /**
     * 获取用户信息
     *
     * @param request HTTP请求
     * @return 用户信息
     */
    @GetMapping("/info")
    public ResultVO<UserInfoVO> getUserInfo(HttpServletRequest request) {
        Long userId = (Long) request.getAttribute("userId");
        UserInfoVO userInfoVO = userService.getUserInfo(userId);
        return ResultVO.success(userInfoVO);
    }
    
    /**
     * 更新用户手机号
     *
     * @param request HTTP请求
     * @param phone   手机号
     * @return 用户信息
     */
    @PutMapping("/phone")
    public ResultVO<UserInfoVO> updatePhone(HttpServletRequest request, @RequestParam String phone) {
        Long userId = (Long) request.getAttribute("userId");
        UserInfoVO userInfoVO = userService.updatePhone(userId, phone);
        return ResultVO.success(userInfoVO);
    }

    /**
     * 微信小程序登录
     *
     * @param params 包含code的请求参数
     * @return 用户信息
     */
    @PostMapping("/wx-login")
    public ResultVO<UserInfoVO> wxLogin(@RequestBody Map<String, String> params) {
        log.info("接收到微信登录请求，参数: {}", params);
        
        String code = params.get("code");
        if (!StringUtils.hasText(code)) {
            log.error("微信授权码为空");
            return ResultVO.error("微信授权码不能为空");
        }
        
        try {
            // 微信小程序配置信息
            String appId = "wx4e2b162ba4de6526";
            String appSecret = "0b2a9253a2ce5a6a7b7a542c9048e566";
            
            // 构建请求URL
            String url = String.format(
                "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
                appId, appSecret, code
            );
            
            log.info("请求微信服务器: {}", url);
            
            // 发送HTTP请求到微信服务器
            RestTemplate restTemplate = new RestTemplate();
            ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
            
            log.info("微信服务器响应: {}", response.getBody());
            
            if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
                // 使用Jackson解析JSON
                ObjectMapper mapper = new ObjectMapper();
                JsonNode jsonNode = mapper.readTree(response.getBody());
                
                // 检查是否有错误信息
                if (jsonNode.has("errcode")) {
                    int errcode = jsonNode.get("errcode").asInt();
                    String errmsg = jsonNode.get("errmsg").asText();
                    log.error("微信服务器返回错误: {} - {}", errcode, errmsg);
                    return ResultVO.error("微信登录失败：" + errmsg);
                }
                
                if (!jsonNode.has("openid")) {
                    log.error("微信服务器响应中缺少openid");
                    return ResultVO.error("微信登录失败：服务器响应异常");
                }
                
                String openid = jsonNode.get("openid").asText();
                String sessionKey = jsonNode.get("session_key").asText();
                
                if (!StringUtils.hasText(openid)) {
                    log.error("获取openid失败");
                    return ResultVO.error("获取openid失败");
                }
                
                log.info("获取到openid: {}", openid);
                
                try {
                    // 根据openid查询或创建用户
                    UserInfoVO userInfo = userService.loginByWechat(openid);
                    log.info("微信登录成功: {}", userInfo);
                    
                    return ResultVO.success(userInfo);
                } catch (Exception e) {
                    log.error("用户服务处理失败", e);
                    return ResultVO.error("用户服务处理失败：" + e.getMessage());
                }
            } else {
                log.error("微信服务器请求失败: {}", response.getStatusCode());
                return ResultVO.error("微信服务器请求失败");
            }
        } catch (Exception e) {
            log.error("微信登录失败", e);
            return ResultVO.error("微信登录失败：" + e.getMessage());
        }
    }

    /**
     * 微信手机号登录
     *
     * @param params 包含code、encryptedData和iv的请求参数
     * @return 用户信息
     */
    @PostMapping("/wx-phone-login")
    public ResultVO<UserInfoVO> wxPhoneLogin(@RequestBody Map<String, String> params) {
        log.info("接收到微信手机号登录请求，参数: {}", params);
        
        String code = params.get("code");
        String encryptedData = params.get("encryptedData");
        String iv = params.get("iv");
        
        if (!StringUtils.hasText(code)) {
            log.error("微信授权码为空");
            return ResultVO.error("微信授权码不能为空");
        }
        
        if (!StringUtils.hasText(encryptedData) || !StringUtils.hasText(iv)) {
            log.error("加密数据或iv为空");
            return ResultVO.error("加密数据不完整");
        }
        
        try {
            // 获取openid和session_key
            String appId = "wx4e2b162ba4de6526";
            String appSecret = "0b2a9253a2ce5a6a7b7a542c9048e566";
            
            String url = String.format(
                "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
                appId, appSecret, code
            );
            
            RestTemplate restTemplate = new RestTemplate();
            ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
            
            if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
                ObjectMapper mapper = new ObjectMapper();
                JsonNode jsonNode = mapper.readTree(response.getBody());
                
                if (jsonNode.has("errcode")) {
                    int errcode = jsonNode.get("errcode").asInt();
                    String errmsg = jsonNode.get("errmsg").asText();
                    log.error("微信服务器返回错误: {} - {}", errcode, errmsg);
                    return ResultVO.error("微信登录失败：" + errmsg);
                }
                
                String openid = jsonNode.get("openid").asText();
                String sessionKey = jsonNode.get("session_key").asText();
                
                // 解密手机号信息
                try {
                    String phoneInfo = wxUtil.decryptPhoneNumber(sessionKey, encryptedData, iv);
                    JsonNode phoneInfoNode = mapper.readTree(phoneInfo);
                    String phoneNumber = phoneInfoNode.get("phoneNumber").asText();
                    
                    // 使用手机号和openid进行登录
                    UserInfoVO userInfo = userService.loginByWechatPhone(openid, phoneNumber);
                    log.info("微信手机号登录成功: {}", userInfo);
                    
                    return ResultVO.success(userInfo);
                } catch (Exception e) {
                    log.error("解密手机号失败", e);
                    return ResultVO.error("解密手机号失败：" + e.getMessage());
                }
            } else {
                log.error("微信服务器请求失败: {}", response.getStatusCode());
                return ResultVO.error("微信服务器请求失败");
            }
        } catch (Exception e) {
            log.error("微信手机号登录失败", e);
            return ResultVO.error("微信手机号登录失败：" + e.getMessage());
        }
    }

    /**
     * 模拟登录接口 - 不需要鉴权
     *
     * @return 用户信息
     */
    @PostMapping("/mock-login")
    public ResultVO<UserInfoVO> mockLogin() {
        log.info("接收到模拟登录请求");
        
        try {
            // 创建模拟用户信息
            UserInfoVO userInfo = new UserInfoVO();
            userInfo.setId(999L);
            userInfo.setNickname("模拟用户");
            userInfo.setAvatarUrl("https://thirdwx.qlogo.cn/mmopen/vi_32/POgEwh4mIHO4nibH0KlMECNjjGxQUq24ZEaGT4poC6icRiccVGKSyXwibcPq4BWmiaIGuG1icwxaQX6grC9VemZoJ8rg/132");
            userInfo.setGender(0);
            userInfo.setPhone("13800138000");
            userInfo.setEmail("mock@example.com");
            userInfo.setIs_vip(1); // 设置为VIP用户
            
            // 生成token
            String token = jwtUtil.generateToken(userInfo.getId());
            userInfo.setToken(token);
            
            // 保存到数据库（可选，如果需要持久化）
            userService.saveMockUser(userInfo);
            
            log.info("模拟登录成功: {}", userInfo);
            return ResultVO.success(userInfo);
        } catch (Exception e) {
            log.error("模拟登录失败", e);
            return ResultVO.error("模拟登录失败：" + e.getMessage());
        }
    }
} 